<template>
  <el-dialog v-model="drawer" title="选择区域" width="800px" custom-class="areaDetail" :append-to-body="true" @close="close">
    <el-scrollbar style="max-height:500px;">
        <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
        <div class="areaList">
            <el-tree :data="citys" show-checkbox node-key="id" ref="tree" :props="{children: 'city'}" @check="checkItem" accordion>
                <template #default="{ node, data }">
                    <span style="font-size:12px;">{{ data.label }}<span class="custom-num" v-if="data.city && data.city.length > 0">({{ (data.cityCheckNum || 0) + '/' + data.city.length }})</span></span>
                </template>
            </el-tree>
        </div>
    </el-scrollbar>
    <el-row class="footer-fixed">
        <el-button type="primary" size="small" @click="submitForm">保存</el-button>
        <el-button size="small" @click="resetForm">取消</el-button>
    </el-row>
  </el-dialog>
</template>

<script>
import { computed, reactive, toRefs, ref, watch, nextTick } from 'vue'
import { city } from '/@/utils/secondCitys'
export default {
    name: 'AreaDetail',
    props: {
        dialogArea: {
            type: Boolean,
            default: false
        },
        areaForm: {
            type: Array,
            default() {
                return []
            }
        }
    },
    emits: ['onAreaSubmit', 'update:dialogArea'],
    setup(props, context){
        const { dialogArea, areaForm } = toRefs(props)
        const tree = ref()
        const drawer = computed({
            get: () => dialogArea.value,
            set: val => {
                context.emit('update:dialogArea', val)
            }
        })
        const form = computed({
            get: () => areaForm.value,
            set: val => {
                context.emit('update:areaForm', val)
            }
        })
        const state = reactive({
            citys: city,
            isIndeterminate: false,
            checkAll: false
        })
        watch(
            () => dialogArea.value,
            () => {
                for(let i = 0; i < state.citys.length; i ++) {
                    state.citys[i].cityCheckNum = 0
                }
                if(form.value.length > 0) {
                    tree.value.setCheckedNodes(form.value)
                    state.isIndeterminate = true
                }else{
                    nextTick(() => {
                        tree.value.setCheckedKeys([]);
                    })
                    state.isIndeterminate = false
                    state.checkAll = false
                }
            }
        )
        const submitForm = () => {
            context.emit('onAreaSubmit', getSimpleCheckedNodeIds(tree.value.store))
            context.emit('update:dialogArea', false)
        }
        const resetForm = () => {
            context.emit('update:dialogArea', false)
        }
        const close = () => {
            context.emit('update:dialogArea', false)
        }
        const handleCheckAllChange = (val) => {
            const check = state.citys.map(item => {
                return item.id
            })
            if(val) {
                tree.value.setCheckedKeys(check); 
            }else{
                tree.value.setCheckedKeys([]); 
            }
            for(let i = 0; i < state.citys.length; i ++) {
                const len = state.citys[i].city.length
                if(val && len) {
                    state.citys[i].cityCheckNum = state.citys[i].city.length
                }else{
                    state.citys[i].cityCheckNum = 0
                }
            }
            state.isIndeterminate = false
        }
        const checkItem = (data, val) => {
            if(data.city){
                const index = state.citys.findIndex(item => {
                    return item.id == data.id
                })
                const idx = val.checkedKeys.findIndex(item => {
                    return item == data.id
                })
                if(idx > -1){
                    state.citys[index].cityCheckNum = data.city.length
                }else{
                    state.checkAll = false
                    state.citys[index].cityCheckNum = 0
                }
            }else{
                const dataId = structuredClone(data)
                const firstId = String(dataId.id).slice(0, 2)
                let parentId = null // 所属的id
                for(let i = 0; i < state.citys.length; i ++){
                    const first = state.citys[i].id.slice(0, 2)
                    if(first == firstId){
                        parentId = state.citys[i].id
                    }
                }
                let checkItems = val.checkedKeys.filter(item => {
                    const e = String(item).slice(0, 2)
                    return e == firstId
                })
                const index = state.citys.findIndex(item => {
                    return item.id == parentId
                })
                checkItems = checkItems.map(item => {
                    return String(item)
                })
                if(checkItems.length > 0){
                    state.citys[index].cityCheckNum = Array.from(new Set(checkItems)).length
                }else{
                    state.citys[index].cityCheckNum = 0
                }
                state.isIndeterminate = true
            }
            if(val.checkedKeys.length == 371){
                state.isIndeterminate = false
                state.checkAll = true
            }else{
                if(val.checkedKeys.length > 0) {
                    state.isIndeterminate = true
                    state.checkAll = false
                }else{
                    state.isIndeterminate = false
                }
            }
        }
        const getSimpleCheckedNodeIds = (originData) => {
            // 定义数组
            const checkedNodeIds = []
            // 判断是否为全选，若为全选状态返回被全选的节点，不为全选状态正常返回被选中的节点
            const isAllChecked = (node) => {
                const childNodes = node.root ? node.root.childNodes : node.childNodes
                childNodes.forEach(child => {
                    if (child.checked) {
                        checkedNodeIds.push(child.data)
                    }
                    if (child.indeterminate) {
                        isAllChecked(child)
                    }
                })
            }
            isAllChecked(originData)
            return checkedNodeIds
        }
        return {
            drawer,
            submitForm,
            resetForm,
            close,
            handleCheckAllChange,
            checkItem,
            tree,
            ...toRefs(state)
        }
    }
}
</script>

<style scoped lang="scss">
.areaList{
    .areaItem{
        width: 25%;
        position: relative;
    }
    .custom-num{
        color: var(--el-color-error);
        font-weight: bold;
        margin-left: 3px;
    }
    :deep(.el-tree) {
        display: flex;
        align-items: stretch;
        flex-wrap: wrap;
        max-height: 300px;
        flex-direction: column;
    }
    :deep(.el-tree-node) {
        position: relative;
    }
}
.footer-fixed{
    position: absolute;
    left: 0;
    bottom: 0;
    right: 0;
    padding: 10px;
    background: #fff;
    z-index: 999;
    display: flex;
    justify-content: center;
    box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 5px 0px, rgba(0, 0, 0, 0.1) 0px 0px 1px 0px;
}
</style>
<style lang="scss">
.el-overlay .el-overlay-dialog .areaDetail .el-dialog__body{
    padding: 0 20px 50px !important;
}
</style>